﻿using System;
using DAL.Engine.Extention;
using DAL.Engine.Interface;

namespace DAL.Engine
{
    /// <summary>
    /// The baase class for all the entities.
    /// </summary>
    public class Entity<TKey> : IEntity<TKey>, IComparable<Entity<TKey>>, IComparable
    {
        #region Properties

        /// <summary>
        /// Specified entitie Id.
        /// </summary>
        public virtual TKey Id
        {
            get;
            set;
        }

        /// <summary>
        /// Determines whether the specified Entity.
        /// </summary>
        public virtual bool IsNew
        {
            get
            {
                return Object.ReferenceEquals(null, Id) ? true : this.Id.Equals(default(TKey));
            }
        }

        #endregion

        #region Compare

        /// <summary>
        /// Determines whether the specified System.Object is equal to the current Entity.
        /// </summary>
        /// <param name="obj">The System.Object to compare with the current Entity.</param>
        /// <returns>True if the specified System.Object is equal to the current Entity.</returns>
        public override bool Equals(object obj)
        {
            return CompareTo(obj) == 0;
        }

        /// <summary>
        /// Compares the current Entity with another Entity
        /// </summary>
        /// <param name="obj">An Entity object to compare with this instance.</param>
        /// <returns>Zero if the specified object is equal to the current Entity.</returns>
        public virtual int CompareTo(object obj)
        {
            return CompareTo(obj as Entity<TKey>);
        }

        /// <summary>
        /// Compares the current Entity with another Entity
        /// </summary>
        /// <param name="other">An Entity object to compare with this instance.</param>
        /// <returns>Zero if the specified Entity is equal to the current Entity.</returns>
        public virtual int CompareTo(Entity<TKey> other)
        {
            return this.Equals<Entity<TKey>, TKey>(other, EqualsStrategyType.ByIdentifier) ? 0 : 1;
        }

        /// <summary>
        /// Serves as a hash function for a particular type.
        /// </summary>
        /// <returns>A hash code for the current Entity.</returns>
        public override int GetHashCode()
        {
            unchecked
            {
                return Equals(Id, default(TKey)) ? base.GetHashCode() : Id.GetHashCode();
            }
        }

        #endregion
    }
}
